/**
 * HTML5+ 串口蓝牙操作工具类
 * 提供完整的蓝牙设备发现、连接、数据传输功能
 * 基于 Android 原生蓝牙 API 实现
 */
function createBluetoothTool() {
	// ==================== 导入 Android 原生类 ====================
	// 导入蓝牙适配器类，用于管理蓝牙功能
	let BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
	// 导入 Intent 类，用于启动系统活动
	let Intent = plus.android.importClass("android.content.Intent");
	// 导入 IntentFilter 类，用于过滤广播消息
	let IntentFilter = plus.android.importClass("android.content.IntentFilter");
	// 导入蓝牙设备类，表示一个蓝牙设备
	let BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
	// 导入 Build 类，用于获取系统版本信息
	let Build = plus.android.importClass("android.os.Build");
	// 导入 UUID 类，用于生成唯一标识符
	let UUID = plus.android.importClass("java.util.UUID");
	// 导入 Toast 类，用于显示提示信息
	let Toast = plus.android.importClass("android.widget.Toast");
	
	// 连接串口设备的 UUID，这是标准的串口通信 UUID
	let MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

	// ==================== 获取系统对象 ====================
	// 获取 plus.android.invoke 方法，用于调用原生方法
	let invoke = plus.android.invoke;
	// 获取默认蓝牙适配器
	let btAdapter = BluetoothAdapter.getDefaultAdapter();
	// 获取当前 Activity 对象
	let activity = plus.android.runtimeMainActivity();

	// ==================== 蓝牙连接相关变量 ====================
	let btSocket = null;        // 蓝牙 Socket 连接对象
	let btInStream = null;      // 蓝牙输入流，用于读取数据
	let btOutStream = null;     // 蓝牙输出流，用于发送数据
	let setIntervalId = 0;      // 定时器 ID，用于数据读取循环

	// ==================== 广播接收器 ====================
	let btFindReceiver = null;    // 蓝牙搜索广播接收器
	let btStatusReceiver = null;  // 蓝牙状态监听广播接收器

	// ==================== 蓝牙状态管理 ====================
	let state = {
		bluetoothEnable: false,        // 蓝牙是否开启
		bluetoothState: "",            // 当前蓝牙状态字符串
		discoveryDeviceState: false,   // 是否正在搜索蓝牙设备
		readThreadState: false,        // 数据读取线程状态
	};

	// ==================== 回调函数配置对象 ====================
	let options = {
		/**
		 * 监听蓝牙状态回调函数
		 * @param {String} state - 蓝牙状态字符串
		 */
		listenBTStatusCallback: function(state) {},
		
		/**
		 * 搜索到新的蓝牙设备回调函数
		 * @param {Object} newDevice - 新发现的设备对象 {name: "设备名", address: "设备地址"}
		 */
		discoveryDeviceCallback: function(newDevice) {},
		
		/**
		 * 停止搜索回调函数
		 */
		cancelDiscoveryCallback: function() {},
		
		/**
		 * 蓝牙搜索完成回调函数
		 */
		discoveryFinishedCallback: function() {},
		
		/**
		 * 接收到数据回调函数
		 * @param {Array} dataByteArr - 接收到的字节数组
		 */
		readDataCallback: function(dataByteArr) {},
		
		/**
		 * 蓝牙连接中断回调函数
		 * @param {Exception} e - 异常对象
		 */
		connExceptionCallback: function(e) {}
	}

	// ==================== 蓝牙工具实例对象 ====================
	let bluetoothToolInstance = {
		state: state,                    // 蓝牙状态对象
		init: init,                      // 初始化函数
		isSupportBluetooth: isSupportBluetooth,           // 检查是否支持蓝牙
		getBluetoothStatus: getBluetoothStatus,           // 获取蓝牙状态
		turnOnBluetooth: turnOnBluetooth,                 // 开启蓝牙
		turnOffBluetooth: turnOffBluetooth,               // 关闭蓝牙
		getPairedDevices: getPairedDevices,               // 获取已配对设备
		discoveryNewDevice: discoveryNewDevice,           // 搜索新设备
		listenBluetoothStatus: listenBluetoothStatus,     // 监听蓝牙状态
		connDevice: connDevice,                           // 连接设备
		disConnDevice: disConnDevice,                     // 断开连接
		cancelDiscovery: cancelDiscovery,                 // 取消搜索
		readData: readData,                               // 读取数据
		sendData: sendData                                // 发送数据
	}
	
	// ==================== 单例模式实现 ====================
	// 如果已经存在实例，直接返回，否则创建新实例
	if (window.bluetoothToolInstance) {
		return window.bluetoothToolInstance;
	} else {
		window.bluetoothToolInstance = bluetoothToolInstance;
		return bluetoothToolInstance;
	}

	/**
	 * 初始化蓝牙工具
	 * @param {Object} setOptions - 回调函数配置对象
	 */
	function init(setOptions) {
		// 合并用户传入的配置选项
		Object.assign(options, setOptions);
		
		// Android 6.0 以后需要申请权限才能使用蓝牙功能
		if (Build.VERSION.SDK_INT >= 6.0) {
			console.log('申请权限')
			requestPermission()
		}
		
		// 获取当前蓝牙状态
		state.bluetoothEnable = getBluetoothStatus();
		// 开始监听蓝牙状态变化
		listenBluetoothStatus();
	}

	/**
	 * 显示简短提示信息
	 * @param {String} msg - 提示信息
	 */
	function shortToast(msg) {
		// 使用 HTML5+ 的 toast 方法显示提示
		plus.nativeUI.toast(msg);
	}

	/**
	 * 检查设备是否支持蓝牙
	 * @return {boolean} 是否支持蓝牙
	 */
	function isSupportBluetooth() {
		if (btAdapter != null) {
			return true;
		}
		return false;
	}
	
	/**
	 * 获取蓝牙的开启状态
	 * @return {boolean} 蓝牙是否已开启
	 */
	function getBluetoothStatus() {
		if (btAdapter != null) {
			return btAdapter.isEnabled();
		}
		return false;
	}

	/**
	 * 开启蓝牙
	 * 如果蓝牙未开启，会弹出系统对话框请求用户开启
	 */
	function turnOnBluetooth() {
		// 检查设备是否支持蓝牙
		if (btAdapter == null) {
			shortToast("没有蓝牙");
			return;
		}
		
		// 如果蓝牙未开启，请求用户开启
		if (!btAdapter.isEnabled()) {
			if (activity == null) {
				shortToast("未获取到activity");
				return;
			} else {
				// 创建开启蓝牙的 Intent
				let intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
				let requestCode = 1;
				// 启动系统对话框请求开启蓝牙
				activity.startActivityForResult(intent, requestCode);
				return;
			}
		} else {
			shortToast("蓝牙已经打开");
		}
	}

	/**
	 * 关闭蓝牙
	 * 会清理所有相关资源
	 */
	function turnOffBluetooth() {
		// 如果蓝牙适配器存在且已开启，则关闭蓝牙
		if (btAdapter != null && btAdapter.isEnabled()) {
			btAdapter.disable();
		}
		
		// 注销蓝牙搜索广播接收器
		if (btFindReceiver != null) {
			try {
				activity.unregisterReceiver(btFindReceiver);
			} catch (e) {
				// 忽略注销异常
			}
			btFindReceiver = null;
		}
		
		// 更新状态
		state.bluetoothEnable = false;
		// 取消搜索
		cancelDiscovery();
		// 关闭蓝牙 Socket
		closeBtSocket();

		// 再次尝试关闭蓝牙并提示
		if (btAdapter != null && btAdapter.isEnabled()) {
			btAdapter.disable();
			shortToast("蓝牙关闭成功");
		} else {
			shortToast("蓝牙已经关闭");
		}
	}

	/**
	 * 获取已经配对的蓝牙设备列表
	 * @return {Array} 已配对设备数组，每个设备包含 name 和 address 属性
	 */
	function getPairedDevices() {
		let pairedDevices = [];

		// 获取 Android 原生的已配对设备集合
		let pairedDevicesAndroid = null;
		if (btAdapter != null && btAdapter.isEnabled()) {
			pairedDevicesAndroid = btAdapter.getBondedDevices();
		} else {
			shortToast("蓝牙未开启");
		}

		// 如果没有配对设备，返回空数组
		if (!pairedDevicesAndroid) {
			return pairedDevices;
		}

		// 遍历 Android 原生设备集合，转换为 JavaScript 数组
		let it = invoke(pairedDevicesAndroid, "iterator");
		while (invoke(it, "hasNext")) {
			let device = invoke(it, "next");
			pairedDevices.push({
				"name": invoke(device, "getName"),      // 设备名称
				"address": invoke(device, "getAddress")  // 设备地址
			});
		}
		return pairedDevices;
	}

	/**
	 * 申请蓝牙和定位权限
	 * Android 6.0+ 需要这些权限才能使用蓝牙功能
	 */
	function requestPermission() {
		// 需要申请的权限列表
		let permission = [
			'android.permission.BLUETOOTH',           // 蓝牙权限
			'android.permission.BLUETOOTH_ADMIN',     // 蓝牙管理权限
			'android.permission.BLUETOOTH_CONNECT',   // 蓝牙连接权限（Android 12+）
			'android.permission.BLUETOOTH_SCAN',      // 蓝牙扫描权限（Android 12+）
			'android.permission.ACCESS_COARSE_LOCATION', // 粗略定位权限
			'android.permission.ACCESS_FINE_LOCATION'     // 精确定位权限
		];
		
		// 申请权限
		plus.android.requestPermissions(permission, function(e) {
			if (e.deniedAlways.length > 0) { 
				// 权限被永久拒绝，需要引导用户到设置页面手动开启
				console.log('Always Denied!!! ' + e.deniedAlways.toString());
			}
			if (e.deniedPresent.length > 0) { 
				// 权限被临时拒绝，可以再次申请
				console.log('Present Denied!!! ' + e.deniedPresent.toString());
			}
			if (e.granted.length > 0) { 
				// 权限被允许，可以正常使用蓝牙功能
				console.log('Granted!!! ' + e.granted.toString());
			}
		}, function(e) {
			// 权限申请失败的回调
			console.log('Request Permissions error:' + JSON.stringify(e));
		});
	}

	/**
	 * 开始搜索新的蓝牙设备
	 * 会注册广播接收器监听设备发现事件
	 */
	function discoveryNewDevice() {
		console.log('开始扫描设备', btFindReceiver)
		
		// 如果已有搜索接收器，先注销
		if (btFindReceiver != null) {
			try {
				activity.unregisterReceiver(btFindReceiver);
			} catch (e) {
				console.error('扫描设备发生错误', e);
			}
			btFindReceiver = null;
			cancelDiscovery();
		}

		// 创建蓝牙设备搜索广播接收器
		btFindReceiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", {
			onReceive: function(context, intent) {
				// 导入 Intent 类
				plus.android.importClass(intent);
				let action = intent.getAction();
				console.log('接收到发现设备广播消息', action)
				
				// 处理找到设备的广播
				if (BluetoothDevice.ACTION_FOUND == action) { 
					// 从 Intent 中获取设备信息
					let device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
					let newDevice = {
						"name": plus.android.invoke(device, "getName"),      // 设备名称
						"address": plus.android.invoke(device, "getAddress")  // 设备地址
					}
					// 调用发现设备的回调函数
					options.discoveryDeviceCallback && options.discoveryDeviceCallback(newDevice);
				}
				
				// 处理搜索完成的广播
				if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) { 
					cancelDiscovery();
					// 调用搜索完成的回调函数
					options.discoveryFinishedCallback && options.discoveryFinishedCallback();
				}
			}
		});

		// 创建 IntentFilter，过滤需要的广播消息
		let filter = new IntentFilter();
		filter.addAction(BluetoothDevice.ACTION_FOUND);           // 设备发现广播
		filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); // 搜索完成广播
		
		console.log('注册发现设备Receiver');
		// 注册广播接收器
		activity.registerReceiver(btFindReceiver, filter);
		
		console.log('开始搜索');
		// 开始搜索蓝牙设备
		btAdapter.startDiscovery(); 
		state.discoveryDeviceState = true;
	}

	/**
	 * 监听蓝牙状态变化
	 * 注册广播接收器监听蓝牙开启/关闭状态
	 */
	function listenBluetoothStatus() {
		// 如果已有状态监听接收器，先注销
		if (btStatusReceiver != null) {
			try {
				activity.unregisterReceiver(btStatusReceiver);
			} catch (e) {
				console.error(e);
			}
			btStatusReceiver = null;
		}

		// 创建蓝牙状态监听广播接收器
		btStatusReceiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", {
			"onReceive": function(context, intent) {
				plus.android.importClass(context);
				plus.android.importClass(intent);

				let action = intent.getAction();
				switch (action) {
					case BluetoothAdapter.ACTION_STATE_CHANGED:
						// 获取蓝牙状态
						let blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
						console.log('蓝牙工具', blueState)
						let stateStr = "";
						
						// 根据状态值设置状态字符串
						switch (blueState) {
							case BluetoothAdapter.STATE_TURNING_ON:
								stateStr = "STATE_TURNING_ON";  // 正在开启
								break;
							case BluetoothAdapter.STATE_ON:
								state.bluetoothEnable = true;
								stateStr = "STATE_ON";          // 已开启
								break;
							case BluetoothAdapter.STATE_TURNING_OFF:
								stateStr = "STATE_TURNING_OFF"; // 正在关闭
								break;
							case BluetoothAdapter.STATE_OFF:
								stateStr = "STATE_OFF";         // 已关闭
								state.bluetoothEnable = false;
								break;
						}
						state.bluetoothState = stateStr;
						// 调用状态变化回调函数
						options.listenBTStatusCallback && options.listenBTStatusCallback(stateStr);
						break;
				}
			}
		});
		
		// 创建 IntentFilter，监听蓝牙状态变化
		let filter = new IntentFilter();
		filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
		// 注册广播接收器
		activity.registerReceiver(btStatusReceiver, filter);
	}

	/**
	 * 根据蓝牙地址连接设备
	 * @param {String} address - 蓝牙设备地址
	 * @return {Boolean} 连接是否成功
	 */
	function connDevice(address) {
		// 导入需要的 Java 类
		let InputStream = plus.android.importClass("java.io.InputStream");
		let OutputStream = plus.android.importClass("java.io.OutputStream");
		let BluetoothSocket = plus.android.importClass("android.bluetooth.BluetoothSocket");

		// 如果已有连接，先断开
		if (btSocket != null) {
			closeBtSocket();
		}
		state.readThreadState = false;

		try {
			// 根据地址获取远程设备
			let device = invoke(btAdapter, "getRemoteDevice", address);
			// 创建 RFCOMM Socket 连接
			btSocket = invoke(device, "createRfcommSocketToServiceRecord", MY_UUID);
		} catch (e) {
			console.error(e);
			shortToast("连接失败，获取Socket失败！");
			return false;
		}
		
		try {
			// 连接设备
			invoke(btSocket, "connect");
			shortToast("连接成功");
		} catch (e) {
			console.error(e);
			shortToast("连接失败");
			return false;
		}
		
		// 连接成功后取消搜索
		cancelDiscovery();
		// 开始读取数据
		readData(); 
		return true;
	}

	/**
	 * 断开蓝牙设备连接
	 * @return {Boolean} 断开是否成功
	 */
	function disConnDevice() {
		if (btSocket != null) {
			closeBtSocket();
		}
		state.readThreadState = false;
		shortToast("断开连接成功");
	}

	/**
	 * 关闭蓝牙 Socket 连接
	 * 清理相关资源
	 */
	function closeBtSocket() {
		state.readThreadState = false;
		if (!btSocket) {
			return;
		}
		try {
			btSocket.close();
		} catch (e) {
			console.error(e);
			btSocket = null;
		}
	}

	/**
	 * 取消蓝牙设备搜索
	 * 停止搜索并清理相关资源
	 */
	function cancelDiscovery() {
		console.log('停止扫描设备')
		// 如果正在搜索，则停止搜索
		if (btAdapter.isDiscovering()) {
			btAdapter.cancelDiscovery();
			options.cancelDiscoveryCallback && options.cancelDiscoveryCallback();
		}
		// 注销搜索广播接收器
		if (btFindReceiver != null) {
			activity.unregisterReceiver(btFindReceiver);
			btFindReceiver = null;
		}
		state.discoveryDeviceState = false;
	}

	/**
	 * 开始读取蓝牙数据
	 * 使用定时器模拟多线程读取
	 * @return {Boolean} 是否成功开始读取
	 */
	function readData() {
		// 检查是否已连接
		if (!btSocket) {
			shortToast("请先连接蓝牙设备！");
			return false;
		}
		
		try {
			// 获取输入输出流
			btInStream = invoke(btSocket, "getInputStream");
			btOutStream = invoke(btSocket, "getOutputStream");
		} catch (e) {
			console.error(e);
			shortToast("创建输入输出流失败！");
			closeBtSocket();
			return false;
		}
		
		let setTimeCount = 0;
		read();
		state.readThreadState = true;
		return true;

		/**
		 * 模拟 Java 多线程读取数据
		 * 使用 setInterval 定时检查是否有新数据
		 */
		function read() {
			// 清除之前的定时器
			clearInterval(setIntervalId);
			// 每 40 毫秒检查一次数据
			setIntervalId = setInterval(function() {
				setTimeCount++;
				if (state.readThreadState) {
					// 最多一次读取 100 个字节
					let max = 100;
					
					// 心跳检测：每 20 次循环发送一次心跳包
					if (setTimeCount % 20 == 0) {
						try {
							btOutStream.write([0b00]);
						} catch (e) {
							state.readThreadState = false;
							options.connExceptionCallback && options.connExceptionCallback(e);
						}
					}
					
					let dataArr = [];
					// 循环读取所有可用数据
					while (invoke(btInStream, "available") !== 0) {
						let data = invoke(btInStream, "read");
						dataArr.push(data);
						max--;
						if (max <= 0) {
							break;
						}
					}
					
					// 如果有数据，调用回调函数
					if (dataArr.length > 0) {
						options.readDataCallback && options.readDataCallback(dataArr);
					}
				}
			}, 40);
		}
	}

	/**
	 * 发送数据到蓝牙设备
	 * @param {Array} bytes - 要发送的字节数组
	 * @return {Boolean} 发送是否成功
	 */
	function sendData(bytes) {
		console.log('写入蓝牙数据', bytes);
		
		// 检查输出流是否存在
		if (!btOutStream) {
			shortToast("蓝牙设备未连接");
			return false;
		}
		
		try {
			// 写入数据
			btOutStream.write(bytes);
		} catch (e) {
			console.error('写入蓝牙数据错误', e);
			return false;
		}
		return true;
	}
};